package jnpf.service.impl;


import com.alibaba.fastjson.JSONObject;
import jnpf.base.service.SysconfigService;
import jnpf.util.mp.WxApiClient;
import jnpf.entity.MpEventContentEntity;
import jnpf.exception.WxErrorException;
import jnpf.model.login.BaseSystemInfo;
import jnpf.model.mpmenu.MpMenuButtonModel;
import jnpf.model.mpmenu.MpMenuModel;
import jnpf.model.mpmenu.MpMenuSubButtonModel;
import jnpf.service.MpEventContentService;
import jnpf.service.MpMenuService;
import jnpf.util.JsonUtil;
import jnpf.util.Md5Util;
import jnpf.util.StringUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 公众号菜单实现类
 *
 * @author 南通渡课开发平台组
 * @version V3.1.0
 * @copyright 南通渡课信息技术有限公司
 * @date 2019年9月27日 上午9:18
 */
@Slf4j
@Service
public class MpMenuServiceImpl implements MpMenuService {

    @Autowired
    private SysconfigService sysconfigService;
    @Autowired
    private MpEventContentService mpEventContentService;

    @Override
    public List<MpMenuModel> getList() throws WxErrorException {
        List<MpMenuModel> menuList = new ArrayList<>();
        BaseSystemInfo config = sysconfigService.getWeChatInfo();
        //获取token
        JSONObject tokenObject = WxApiClient.getAccessToken(config.getWxGzhAppId(), config.getWxGzhAppSecret());
        //菜单列表
        JSONObject result = WxApiClient.menuList(tokenObject.getString("access_token"));
        JSONObject menuJson = result.getJSONObject("menu");
        if (null != menuJson) {
            List<MpMenuButtonModel> menuButtonList = JsonUtil.getJsonToList(menuJson.getString("button"), MpMenuButtonModel.class);
            for (MpMenuButtonModel menuButton : menuButtonList) {
                MpMenuModel menu = new MpMenuModel();
                menu.setId(Md5Util.getStringMd5(menuButton.getName()));
                menu.setKey(menuButton.getKey());
                menu.setFullName(menuButton.getName());
                menu.setParentId("0");
                menu.setType(menuButton.getType());
                menu.setUrl(menuButton.getUrl());
                menu.setSortCode(Long.parseLong(menuButtonList.indexOf(menuButton) + ""));
                menuList.add(menu);
                if (menuButton.getSubButton().size() > 0) {
                    for (MpMenuSubButtonModel menuSubButton : menuButton.getSubButton()) {
                        MpMenuModel button = new MpMenuModel();
                        button.setId(Md5Util.getStringMd5(menuSubButton.getName()));
                        button.setKey(menuSubButton.getKey());
                        button.setFullName(menuSubButton.getName());
                        button.setParentId(menu.getId());
                        button.setType(menuSubButton.getType());
                        button.setUrl(menuSubButton.getUrl());
                        button.setSortCode(Long.parseLong(menuButton.getSubButton().indexOf(menuSubButton) + ""));
                        menuList.add(button);
                    }
                }
            }
        }
        return menuList;
    }

    @Override
    public void syncMenu(List<MpMenuModel> menuList) throws WxErrorException {
        BaseSystemInfo config = sysconfigService.getWeChatInfo();
        List<MpMenuButtonModel> menuButtonList = new ArrayList<>();
        if (menuList.size() > 0) {
            List<MpMenuModel> menuParentList = menuList.stream().filter(m -> "0".equals(m.getParentId())).collect(Collectors.toList());
            for (MpMenuModel item : menuParentList) {
                if (menuList.stream().filter(m -> m.getParentId().equals(item.getId())).count() > 0) {
                    item.setType("");
                } else {
                    if (menuList.stream().filter(m -> m.getParentId().equals(item.getId())).count() == 0 && "view".equals(item.getType())) {
                        item.setType("view");
                    } else {
                        item.setType("click");
                        item.setKey(Md5Util.getStringMd5(item.getFullName()));
                    }
                }
                MpMenuButtonModel menu = new MpMenuButtonModel();
                menu.setKey("view".equals(item.getType()) ? null : item.getKey());
                menu.setName(item.getFullName());
                menu.setType(item.getType());
                menu.setUrl(item.getUrl());
                if (StringUtil.isEmpty(item.getType())) {
                    List<MpMenuModel> menuSubList = menuList.stream().filter(m -> m.getParentId().equals(item.getId())).collect(Collectors.toList());
                    List<MpMenuSubButtonModel> subButton = new ArrayList<>();
                    for (MpMenuModel subItem : menuSubList) {
                        if ("click".equals(subItem.getType())) {
                            subItem.setKey(Md5Util.getStringMd5(subItem.getFullName()));
                        }
                        MpMenuSubButtonModel button = new MpMenuSubButtonModel();
                        button.setKey("view".equals(subItem.getType()) ? null : subItem.getKey());
                        button.setName(subItem.getFullName());
                        button.setType(subItem.getType());
                        button.setUrl(subItem.getUrl());
                        subButton.add(button);
                    }
                    menu.setSubButton(subButton);
                }
                menuButtonList.add(menu);
            }
        }
        //旧数据防止创建失败回滚到旧数据
        JSONObject tokenObject = WxApiClient.getAccessToken(config.getWxGzhAppId(), config.getWxGzhAppSecret());
        String token = tokenObject.getString("access_token");
        JSONObject result = WxApiClient.menuList(token);
        JSONObject menu = result.getJSONObject("menu");
        //删除菜单
        WxApiClient.deleteMenu(token);
        //创建菜单
        if (menuButtonList.size() > 0) {
            JSONObject object = new JSONObject();
            object.put("button", menuButtonList);
            JSONObject returnObject = WxApiClient.publishMenus(object.toString(), token);
            if (returnObject.getInteger("errcode") != 0 && menu != null) {
                //回滚老数据
                WxApiClient.publishMenus(menu.toJSONString(), token);
            }
        }
    }

    @Override
    public boolean isExistByFullName(String fullName, String id) throws WxErrorException {
        List<MpMenuModel> menuList = this.getList();
        menuList = menuList.stream().filter(m -> String.valueOf(m.getFullName()).equals(String.valueOf(fullName))).collect(Collectors.toList());
        if (!StringUtil.isEmpty(id)) {
            menuList = menuList.stream().filter(t -> !t.getId().equals(id)).collect(Collectors.toList());
        }
        return menuList.size() > 0 ? true : false;
    }

    @Override
    public void create(MpMenuModel model) {
        MpEventContentEntity entity = new MpEventContentEntity();
        entity.setEventKey(Md5Util.getStringMd5(model.getFullName()));
        entity.setContent(model.getContent());
        mpEventContentService.create(entity);
    }

    @Override
    public boolean update(String id, MpMenuModel model) {
        MpEventContentEntity entity = mpEventContentService.getInfo(id);
        if (entity != null) {
            entity.setEventKey(id);
            entity.setContent(model.getContent());
            return  mpEventContentService.update(entity);
        }
        return false;
    }

    @Override
    public boolean delete(String id) {
        MpEventContentEntity entity = mpEventContentService.getInfo(id);
        if (entity != null) {
           return  mpEventContentService.delete(entity);
        }
        return false;
    }

    @Override
    public void first(String id) throws WxErrorException {
        List<MpMenuModel> menuList = this.getList();
        MpMenuModel currentEntity = menuList.stream().filter(m -> m.getId().equals(id)).findFirst().get();
        Long currentSortCode = currentEntity.getSortCode() == null ? 0 : currentEntity.getSortCode();
        List<MpMenuModel> upEntitys = menuList.stream()
                .filter(t -> t.getParentId().equals(currentEntity.getParentId()))
                .filter(n -> n.getSortCode() < currentSortCode).collect(Collectors.toList());
        upEntitys.sort(Comparator.comparing(MpMenuModel::getSortCode).reversed());
        MpMenuModel upEntity = new MpMenuModel();
        if (upEntitys.size() != 0) {
            upEntity = upEntitys.get(0);
            currentEntity.setSortCode(upEntity.getSortCode());
            upEntity.setSortCode(currentSortCode);
            menuList.remove(currentEntity);
            menuList.remove(upEntity);
            menuList.add(currentEntity);
            menuList.add(upEntity);
            this.syncMenu(menuList);
        }
    }

    @Override
    public void next(String id) throws WxErrorException {
        List<MpMenuModel> menuList = this.getList();
        MpMenuModel currentEntity = menuList.stream().filter(m -> m.getId().equals(id)).findFirst().get();
        Long currentSortCode = currentEntity.getSortCode() == null ? 0 : currentEntity.getSortCode();
        List<MpMenuModel> upEntitys = menuList.stream()
                .filter(t -> t.getParentId().equals(currentEntity.getParentId()))
                .filter(n -> n.getSortCode() > currentSortCode).collect(Collectors.toList());
        upEntitys.sort(Comparator.comparing(MpMenuModel::getSortCode));
        if (upEntitys.size() != 0) {
            MpMenuModel nextEntity = upEntitys.get(0);
            currentEntity.setSortCode(nextEntity.getSortCode());
            nextEntity.setSortCode(currentSortCode);
            menuList.remove(currentEntity);
            menuList.remove(nextEntity);
            menuList.add(currentEntity);
            menuList.add(nextEntity);
            this.syncMenu(menuList);
        }
    }
}
